package com.situ.thread;

import java.util.concurrent.atomic.AtomicStampedReference;

public class AtomicStampedReferenceExample {
    private static AtomicStampedReference<Boolean> OPEN_OR_CLOSE = new AtomicStampedReference<>(false, 0);
    public static void main(String[] args) throws InterruptedException {
        boolean expectedReference = OPEN_OR_CLOSE.getReference();
        boolean newReference = true;
        int expectedStamp = OPEN_OR_CLOSE.getStamp();
        Thread zhangsan = new Thread(new Runnable() {
            @Override
            public void run() {
                boolean isOpen = OPEN_OR_CLOSE.compareAndSet(expectedReference, newReference, expectedStamp, expectedStamp + 1);
                System.out.println(Thread.currentThread().getName() + "开柜门：" + isOpen);
                // 省略 偷试题的操作
                boolean isClose = OPEN_OR_CLOSE.compareAndSet(newReference, expectedReference, OPEN_OR_CLOSE.getStamp(), OPEN_OR_CLOSE.getStamp() + 1);
                System.out.println(Thread.currentThread().getName() + "关柜门：" + isClose);
                System.out.println(Thread.currentThread().getName() + "偷题是否成功" + (isOpen && isClose));
            }
        }, "zhangsan");

        Thread lisi = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    // 张三使手段，确保自己先执行完，真实场景可能用其它的手段
                    zhangsan.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "打开之前门状态为：" + OPEN_OR_CLOSE.getReference());
                boolean isOpen = OPEN_OR_CLOSE.compareAndSet(expectedReference, newReference, expectedStamp, expectedStamp + 1);
                System.out.println(Thread.currentThread().getName() + "打开之后门状态为：" + OPEN_OR_CLOSE.getReference() + ", "
                        + Thread.currentThread().getName() + "开柜门是否成功：" + isOpen);
            }
        }, "lisi");
        // 当然这个地方最好用 发令枪做，同时起跑
        zhangsan.start();
        lisi.start();
    }
}
